package cn.ywyu.classfinal.util;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.Optional;
import java.util.zip.CRC32;

/**
 * 工具
 */
public class IoUtils {

    /**
     * 写文件
     *
     * @param file      文件
     * @param fileBytes 字节
     */
    public static void writeFile(File file, byte[] fileBytes) {
        createParentDirs(file);
        try {
            Files.write(file.toPath(), fileBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写文件
     *
     * @param file 文件
     * @param txt  内容
     */
    public static void writeTxtFile(File file, String txt) {
        createParentDirs(file);
        try (BufferedWriter out = new BufferedWriter(new FileWriter(file))) {
            out.write(txt);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建父目录
     *
     * @param file 文件
     */
    private static void createParentDirs(File file) {
        File parentDir = file.getParentFile();
        if (parentDir != null && !parentDir.exists()) {
            parentDir.mkdirs();
        }
    }

    /**
     * 读取文件
     *
     * @param file 文件
     * @return 字节
     */
    public static byte[] readFileToByte(File file) {
        try (FileInputStream inputStream = new FileInputStream(file)) {
            return toBytes(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new byte[0];
    }

    /**
     * stream2byte[]
     *
     * @param input 输入流
     * @return 字节
     * @throws IOException IOException
     */
    public static byte[] toBytes(InputStream input) throws IOException {
        try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[4096];
            int n = 0;
            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
            }
            return output.toByteArray();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 递归查找文件，只返回文件
     *
     * @param fileList 返回的文件列表
     * @param dir      目录
     * @param endWith  文件后缀
     */
    public static void listFile(List<File> fileList, File dir, String endWith) {
        if (!dir.exists()) {
            throw new IllegalArgumentException("目录[" + dir.getAbsolutePath() + "]不存在");
        }
        File[] files = Optional.ofNullable(dir.listFiles()).orElse(new File[0]);
        for (File f : files) {
            if (f.isDirectory()) {
                listFile(fileList, f, endWith);
            } else if (f.isFile() && f.getName().endsWith(endWith)) {
                fileList.add(f);
            }
        }
    }

    /**
     * 枚举所有文件，包括文件夹
     *
     * @param filesList 返回的文件列表
     * @param dir       目录
     */
    public static void listFile(List<File> filesList, File dir) {
        if (!dir.exists()) {
            throw new IllegalArgumentException("目录[" + dir.getAbsolutePath() + "]不存在");
        }
        File[] files = Optional.ofNullable(dir.listFiles()).orElse(new File[0]);
        for (File f : files) {
            filesList.add(f);
            if (f.isDirectory()) {
                listFile(filesList, f);
            }
        }
    }

    /**
     * 删除整个目录
     *
     * @param dir 目录
     */
    public static void delete(File dir) {
        if (!dir.exists()) {
            return;
        }
        if (dir.isFile()) {
            dir.delete();
        } else {
            File[] files = Optional.ofNullable(dir.listFiles()).orElse(new File[0]);
            for (File f : files) {
                delete(f);
            }
        }
        dir.delete();
    }

    /**
     * 计算cec
     *
     * @param bytes 字节
     * @return crc值
     */
    public static long crc32(byte[] bytes) {
        CRC32 crc = new CRC32();
        crc.update(bytes);
        return crc.getValue();
    }

    /**
     * 读取文本文件
     *
     * @param file 文件
     * @return 内容
     */
    public static String readTxtFile(File file) {
        StringBuilder txt = new StringBuilder();

        try (
                InputStreamReader read = new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8);
                BufferedReader bufferedReader = new BufferedReader(read);
        ) {
            String lineTxt;
            while ((lineTxt = bufferedReader.readLine()) != null) {
                txt.append(lineTxt).append("\r\n");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return txt.toString();
    }

    /**
     * 合并byte[]
     *
     * @param bts 字节数组
     * @return 合并后的字节
     */
    public static byte[] merger(byte[]... bts) {
        int lenght = 0;
        for (byte[] b : bts) {
            lenght += b.length;
        }

        byte[] bt = new byte[lenght];
        int lastLength = 0;
        for (byte[] b : bts) {
            System.arraycopy(b, 0, bt, lastLength, b.length);
            lastLength += b.length;
        }
        return bt;
    }

}
